package com.google.code.garbagecan.cassandrastudy.astyanax;


import com.netflix.astyanax.AstyanaxContext;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.annotations.Component;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.model.*;
import com.netflix.astyanax.serializers.AnnotatedCompositeSerializer;
import com.netflix.astyanax.serializers.StringSerializer;

/*
==========================================================================

create column family users
  with key_validation_class = 'UTF8Type'
  and comparator = 'CompositeType(UTF8Type, UTF8Type, UTF8Type, UTF8Type)'
  and caching='ALL'
  and column_metadata = [
    {column_name : 'name', validation_class : UTF8Type},
    {column_name : 'first_name', validation_class : UTF8Type},
    {column_name : 'last_name', validation_class : UTF8Type},
    {column_name : 'age', validation_class : LongType}
   ];

list users;
Using default limit of 100
Using default column limit of 100
-------------------
RowKey: 2
=> (column=Mandy:Yuan:Jing:age, value=00000018, timestamp=1368427225226000)
=> (column=Mandy:Yuan:Jing:col1, value=6d7920636f6c31, timestamp=1368427225226000)
=> (column=Mandy:Yuan:Jing:col2, value=6d7920636f6c32, timestamp=1368427225226000)
=> (column=Mandy:Yuan:Jing:col3, value=6d7920636f6c33, timestamp=1368427225226000)
-------------------
RowKey: 1
=> (column=Kongxx:Fanbin:Kong:age, value=00000018, timestamp=1368427225226000)
=> (column=Kongxx:Fanbin:Kong:col1, value=6d7920636f6c31, timestamp=1368427225226000)
=> (column=Kongxx:Fanbin:Kong:col2, value=6d7920636f6c32, timestamp=1368427225226000)
=> (column=Kongxx:Fanbin:Kong:col3, value=6d7920636f6c33, timestamp=1368427225226000)

==========
> select * from users;

 key | column1 | column2 | column3 | column4 | value
-----+---------+---------+---------+---------+------------------
   2 |   Mandy |    Yuan |    Jing |     age |       0x00000018
   2 |   Mandy |    Yuan |    Jing |    col1 | 0x6d7920636f6c31
   2 |   Mandy |    Yuan |    Jing |    col2 | 0x6d7920636f6c32
   2 |   Mandy |    Yuan |    Jing |    col3 | 0x6d7920636f6c33
   1 |  Kongxx |  Fanbin |    Kong |     age |       0x00000018
   1 |  Kongxx |  Fanbin |    Kong |    col1 | 0x6d7920636f6c31
   1 |  Kongxx |  Fanbin |    Kong |    col2 | 0x6d7920636f6c32
   1 |  Kongxx |  Fanbin |    Kong |    col3 | 0x6d7920636f6c33

==========================================================================
create table users (
  id text,
  name text,
  first_name text,
  last_name text,
  age int,
  col1 text,
  col2 text,
  col3 text,
  primary key (id, name, first_name, last_name)
);
==========
list users;
Using default limit of 100
Using default column limit of 100
-------------------
RowKey: 2
=> (column=Mandy:Yuan:Jing:age, value=00000018, timestamp=1368425445032000)
=> (column=Mandy:Yuan:Jing:col1, value=6d7920636f6c31, timestamp=1368425445032000)
=> (column=Mandy:Yuan:Jing:col2, value=6d7920636f6c32, timestamp=1368425445032000)
=> (column=Mandy:Yuan:Jing:col3, value=6d7920636f6c33, timestamp=1368425445032000)
-------------------
RowKey: 1
=> (column=Kongxx:Fanbin:Kong:age, value=00000018, timestamp=1368425445032000)
=> (column=Kongxx:Fanbin:Kong:col1, value=6d7920636f6c31, timestamp=1368425445032000)
=> (column=Kongxx:Fanbin:Kong:col2, value=6d7920636f6c32, timestamp=1368425445032000)
=> (column=Kongxx:Fanbin:Kong:col3, value=6d7920636f6c33, timestamp=1368425445032000)

==========
> select * from users;

 id | name   | first_name | last_name | age | col1    | col2    | col3
----+--------+------------+-----------+-----+---------+---------+---------
  2 |  Mandy |       Yuan |      Jing |  24 | my col1 | my col2 | my col3
  1 | Kongxx |     Fanbin |      Kong |  24 | my col1 | my col2 | my col3

*/

public class CompoundPrimaryKeyTest {

	public static void main(String[] args) throws Exception {
		//insert();
		query();
	}

	public static void insert() throws Exception {
		AstyanaxContext<Keyspace> context = DBUtils.getContext();
		context.start();

		Keyspace keyspace = context.getClient();
		MutationBatch mb = keyspace.prepareMutationBatch();

		AnnotatedCompositeSerializer entitySerializer = new AnnotatedCompositeSerializer(User.class);
		ColumnFamily<String, User> cf = new ColumnFamily<String, User>("users", StringSerializer.get(), entitySerializer);

		User user;

		user = new User("Kongxx", "Fanbin", "Kong");
		user.setField("age");
		mb.withRow(cf, "1").putColumn(user, 24);
		user.setField("col1");
		mb.withRow(cf, "1").putColumn(user, "my col1");
		user.setField("col2");
		mb.withRow(cf, "1").putColumn(user, "my col2");
		user.setField("col3");
		mb.withRow(cf, "1").putColumn(user, "my col3");

		user = new User("Mandy", "Yuan", "Jing");
		user.setField("age");
		mb.withRow(cf, "2").putColumn(user, 24);
		user.setField("col1");
		mb.withRow(cf, "2").putColumn(user, "my col1");
		user.setField("col2");
		mb.withRow(cf, "2").putColumn(user, "my col2");
		user.setField("col3");
		mb.withRow(cf, "2").putColumn(user, "my col3");

		mb.execute();

		context.shutdown();
	}

	public static void query() throws Exception {
		AstyanaxContext<Keyspace> context = DBUtils.getContext();
		context.start();

		Keyspace keyspace = context.getClient();

		AnnotatedCompositeSerializer<User> entitySerializer = new AnnotatedCompositeSerializer<User>(User.class);
		ColumnFamily<String, User> cf = new ColumnFamily<String, User>("users", StringSerializer.get(), entitySerializer);
		keyspace.prepareQuery(cf).getAllRows();
		OperationResult<ColumnList<User>> result = keyspace.prepareQuery(cf).getKey("2").execute();
		ColumnList<User> columns = result.getResult();
		for (Column<User> column : columns){
			User user = column.getName();
			if (user.getField().equals("age")) {
				System.out.println(user.getField() + ": " + column.getIntegerValue());
			} else {
				System.out.println(user.getField() + ": " + column.getStringValue());
			}

		}

		context.shutdown();
	}

	public static class User {
		@Component(ordinal = 0)
		private String name;
		@Component(ordinal = 1)
		private String first_name;
		@Component(ordinal = 2)
		private String last_name;
		@Component(ordinal = 3)
		public String field;

		public User() {

		}

		public User(String name, String first_name, String last_name) {
			this.name = name;
			this.first_name = first_name;
			this.last_name = last_name;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getFirst_name() {
			return first_name;
		}

		public void setFirst_name(String first_name) {
			this.first_name = first_name;
		}

		public String getLast_name() {
			return last_name;
		}

		public void setLast_name(String last_name) {
			this.last_name = last_name;
		}

		public String getField() {
			return field;
		}

		public void setField(String field) {
			this.field = field;
		}

	}
}
